(function(namespace) {

	/**
	 * 1.节点用样式absolute设置top 和left 是相对于父节点的位置的。与offset.top和left 是完全不同的两个东西
	 * 2.jquery.width 在未显示的时候竟然能取到值，很想知道是怎么做到的
	 * 3.**在css里面引入的 url 路径可以直接写当前目录 比较方便 但是写相对路径也可以
	 * 4.数组连接concat  每次携程contact
	 */
	var body_menu = "body_menu";

	var area_div_menu = "area_div_menu";

	var row_menu = "row_menu";
	var row_mouse_over = "row_mouse_over";
	var norow_menu = "norow_menu";
	var text_cell_menu = "text_cell_menu";
	var img_cell_menu = "img_cell_menu";
	var next_cell_menu = "next_cell_menu";

	var imgcell_mouse_over = "imgcell_mouse_over";
	var textcell_mouse_over = "textcell_mouse_over";
	var nextcell_mouse_over = "nextcell_mouse_over";
	var next_img_menu = "next_img_menu";

	var img_checkbox_icon = "img_checkbox_icon";
	var img_radio_icon = "img_radio_icon";

	var img_icon = "img_icon";

	var next_gif = "next.gif";
	var item_width = 215;
	var itemHeight = 21;

	function XMenu(wnd, parentDom, json) {
		this.options = options || {};
		var options = this.options;
		this.wnd = wnd || window;
		this.doc = this.wnd.document;
		this.parentDom = parentDom || this.doc.body;
		this.items = [];
		/**
		 * group { groupid:{ type:checkbox/radio,多选或者单选 items : [] } }
		 */
		this.groups = {};
		_initUI.call(this);
		_initEvents.call(this);
		this.loadFromJson(json);
	}

	/**
	 * 初始dom
	 */
	function _initUI() {
		this.body = $("<table>").addClass(body_menu).appendTo(this.parentDom);
		this.areaDiv = $("<div>").addClass(area_div_menu);
	}

	function _initEvents() {
		$(document.body).bind("mousedown", function() {
			this.hidden();
		}.bind(this));
		this.body.bind("mouseout", function() {
			this.areaDiv.css("display", "none");
		}.bind(this));
	}

	/**
	 * 添加一个子菜单
	 * 
	 * @param caption
	 * @param func
	 * @param img
	 * @param groupid
	 * @returns {XItem}
	 */
	XMenu.prototype.addItem = function(caption, func, img, group) {
		if (!group) group = {
			id : null,
			type : null
		}
		var options = {
			caption : caption,
			img : img,
			func : func,
			owner : this,
			groupid : group.id,
			grouptype : group.type
		};
		var item = new XItem(options);
		this.items.push(item);
		return item;
	};

	/**
	 * { item1 :{caption:123,icon:"",func:func} item2 :{ item3:{ } } }
	 * 
	 * @param json
	 */
	XMenu.prototype.loadFromJson = function(json) {
	};
	XMenu.prototype.hidden = function() {
		this.body.css({
			display : "none"
		});
	};
	/**
	 * 出现在光标处
	 */
	XMenu.prototype.showAtCursor = function() {
		var e = event || window.event;
		var x = e.clientX, y = e.clientY;
		this.showAtPosition(x, y);
	};
	/**
	 * 出现在自定义位置
	 */
	XMenu.prototype.showAtPosition = function(x, y) {
		var bodyWidth = $(document.body).width();
		var bodyHeight = $(document.body).height();
		if (!this.parentItem) {
			var menuHeight = this.body.height();
			var menuWidth = this.body.width();
			if (bodyHeight - y < menuHeight) {
				y = y - menuHeight;
			}
			if (bodyWidth - x < menuWidth) {
				x = bodyWidth - menuWidth - 1;
			}
		} else {
			var menuHeight = this.body.height();
			var menuWidth = this.body.width();
			var parentOffset = this.parentItem.row.offset();
			x = item_width;
			y = -1;
			var ActX = parentOffset.left + item_width;// ActX是相对于窗口的实际位置offset.top，top
														// 因为这里的位置x是相对于的父节点
			var ActY = parentOffset.top;
			if (bodyWidth - ActX < menuWidth) {
				x = -item_width;
			}
			if (bodyHeight - ActY < menuHeight) {
				y = -menuHeight + itemHeight - 1;
			}
		}
		this.body.css({
			display : "block",
			left : x + 1,
			top : y + 1
		});
	};

	/**
	 * 将items添加到指定组
	 */
	XMenu.prototype.addGroup = function(items, groupid, type) {
		if (!items) return;
		if (!(Object.prototype.toString.call(items) === "[object Array]")) {
			items = [ items ];
		}
		var group = this.groups[groupid];
		if (!group) {
			group = this.groups[groupid] = {type : type};
		}
		var curitems = group["items"];
		if (curitems) {
			group["items"] = curitems.concat(items);
		} else {
			this.groups[groupid]["items"] = items;
		}
		for ( var i = 0, len = items.length; i < len; i++) {
			items[i].groupid = groupid;
			items[i].grouptype = type;
		}
	};

	/**
	 * 移除组
	 */
	XMenu.prototype.removeGroup = function(items) {
		if (!items) return;
		if (!(Object.prototype.toString.call(items) === "[object Array]")) {
			items = [ items ];
		}
		for ( var i = 0, len = items.length; i < len; i++) {
			var id = items[i].groupid;
			var group = this.groups[id];
			if(!group) continue;
			var curitem = group["items"];
			if (curitem.length) {
				var index = curitem.indexOf(items[i]);
				if (index !== -1) {
					curitem.splice(index, 1);
				}
			}
			delete items[i]["groupid"];
		}
	};

	/**
	 * 子菜单
	 */
	function XItem(options) {
		this.options = options || {};
		var options = this.options;
		for ( var i in options) {
			this[i] = options[i];
		}
		_initItemUI.call(this);
		_initItemEvent.call(this);
	}

	function _initItemUI() {
		var table = this.owner.body;
		this.row = $("<tr>").appendTo(table);
		this.imgcell = $("<td>").addClass(img_cell_menu).appendTo(this.row);
		this.imgicon = $("<div>").appendTo(this.imgcell);
		this.textcell = $("<td>").addClass(text_cell_menu).appendTo(this.row);
		this.nextcell = $("<td>").addClass(next_cell_menu).appendTo(this.row);
		this.nextimg = $("<div>").addClass(next_img_menu)
				.appendTo(this.nextcell);
		if (this.caption == "--") {
			this.textcell.addClass(norow_menu);
			this.nextcell.addClass(norow_menu);
			this.isLine = true;
			return;
		} else {
			this.row.addClass(row_menu);
			this.textcell.text(this.caption);
			this.imgicon.addClass(img_icon);
			if (this.groupid) {
				this.addGroup(this.groupid, this.grouptype);
			} else {
				if (this.img) {
					this.imgicon[0].style.cssText+=";background:url("+this.img+") no-repeat 0;";
				}
			}
		}
	}

	/**
	 * 绑定事件
	 */
	function _initItemEvent() {
		if (this.isLine) return;
		this.row.bind({
			"mouseover" : on_mouse_over_item.bind(this),
			"mouseout" : on_mouse_out_item.bind(this),
			"mousedown" : on_mouse_down_item.bind(this)
		});
	}

	/**
	 * 鼠标按下事件
	 */
	function on_mouse_down_item() {
		if (typeof this.func == "function") {
			this.func(this);
		}
		if(this.groupid){
			if(this.grouptype =="radio"){
				this.setSelected(true);
			}else if(this.grouptype== "checkbox"){
				this.setSelected(!this.isSelected);
			}
		}
		
	}
	/**
	 * 移入事件
	 */
	function on_mouse_over_item() {
		var owner = this.owner;
		this.row.append(owner.areaDiv);
		owner.areaDiv.css({
			display : "block"
		});
		if (this.subMenu) {
			this.subMenu.showAtPosition();
		}
		// this.imgcell.addClass(imgcell_mouse_over);
		// this.textcell.addClass(textcell_mouse_over);
		// this.nextcell.addClass(nextcell_mouse_over);

	}
	/**
	 * 移除事件
	 */
	function on_mouse_out_item() {
		if (this.subMenu) {
			this.subMenu.hidden();
		}
		// this.imgcell.removeClass(imgcell_mouse_over);
		// this.textcell.removeClass(textcell_mouse_over);
		// this.nextcell.removeClass(nextcell_mouse_over);
	}
	/**
	 * 添加子菜单
	 * 
	 * @param json
	 */
	XItem.prototype.addSubMenu = function(json) {
		if (this.isLine) return;
		var owner = this.owner;
		this.nextimg.css("display", "block");
		this.subMenu = new XMenu(owner.wnd, this.row, json);
		this.subMenu.parentItem = this;
		return this.subMenu;
	};

	/**
	 * 设置选中
	 * @param yes
	 */
	XItem.prototype.setSelected = function(yes) {
		if (!this.groupid) return;
		var owner = this.owner;
		var group = owner.groups[this.groupid]
		var type = group.type;
		var selected = group.selected;
		if ("checkbox" == type) {
			if (yes) {
				this.imgicon.addClass(img_checkbox_icon);
				if(!group.selected){
					selected = group.selected = [];
				}
				selected.push(this);
				this.isSelected = true;
			} else {
				this.imgicon.removeClass(img_checkbox_icon);
				var index = selected.indexOf(this);
				if (index !== -1) {
					selected.slice(index, 1);
				}
				this.isSelected = false;
			}
		} else {
			if (yes) {
				if (selected) selected.imgicon.removeClass(img_radio_icon);
				this.imgicon.addClass(img_radio_icon);
				group.selected = this;
				this.isSelected = true;
			} else {
				// 单元只有一个选中
			}
		}
	};

	/**
	 * 添加到某个分组
	 * 
	 * @param groupid
	 */
	XItem.prototype.addGroup = function(groupid, type) {
		var owner = this.owner;
		if (this.groupid) {
			owner.removeGroup(this);
		}
		owner.addGroup(this, groupid, type);
	};
	namespace["XMenu"] = XMenu;
})(window);